Core Module Orchestration

**Referenced Files in This Document** - [main.js](file://src/assets/js/main.js) - [navigation.js](file://src/assets/js/modules/navigation.js) - [theme-toggling.js](file://src/assets/js/modules/theme-toggling.js) - [custom-cursor.js](file://src/assets/js/modules/custom-cursor.js) - [hero-animations.js](file://src/assets/js/modules/hero-animations.js) - [scroll-nav-polish.js](file://src/assets/js/modules/scroll-nav-polish.js) - [carousel-system.js](file://src/assets/js/modules/carousel-system.js) - [team-card-flip.js](file://src/assets/js/modules/team-card-flip.js) - [accordion.js](file://src/assets/js/modules/accordion.js) - [poll-bar-animation.js](file://src/assets/js/modules/poll-bar-animation.js) - [material-design-3-main-theme-toggle.js](file://src/assets/js/modules/material-design-3-main-theme-toggle.js) - [iaa-alliance-theme-toggle.js](file://src/assets/js/modules/iaa-alliance-theme-toggle.js) - [search-functionality.js](file://src/assets/js/modules/search-functionality.js) - [newsletter-spam-protection.js](file://src/assets/js/modules/newsletter-spam-protection.js) - [package.json](file://package.json)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion

Introduction

This document explains the core module orchestration system centered on main.js. It describes how main.js acts as the central orchestrator that imports and initializes all JavaScript modules upon DOMContentLoaded. It documents the module import patterns, initialization sequence, and dependency management. It also covers the progressive enhancement approach where core functionality remains usable without JavaScript, with modern enhancements layered on top. Practical examples include module registration, error handling during initialization, and conditional loading strategies. Initialization order requirements, lifecycle management, cleanup procedures, performance considerations (lazy loading, bundling, memory), and debugging techniques for initialization failures are included.

Project Structure

The JavaScript runtime is organized into a single entry point main.js that imports modular feature initializers from src/assets/js/modules/*. Each module exports an init function responsible for binding DOM events, observing elements, and setting up interactive behavior. The build pipeline integrates Pagefind for search indexing via an Eleventy command.

graph TB
Entry["main.js<br/>Entry Point"] --> Nav["navigation.js<br/>initNavigation()"]
Entry --> ThemeToggleMain["material-design-3-main-theme-toggle.js<br/>initThemeToggle()"]
Entry --> Cursor["custom-cursor.js<br/>initCustomCursor()"]
Entry --> Hero["hero-animations.js<br/>initHeroAnimations()<br/>initScrollReveals()"]
Entry --> ScrollPolish["scroll-nav-polish.js<br/>initScrollPolish()"]
Entry --> Carousels["carousel-system.js<br/>initCarousels()"]
Entry --> TeamFlip["team-card-flip.js<br/>initTeamCardFlip()"]
Entry --> Accordion["accordion.js<br/>initAccordion()"]
Entry --> Poll["poll-bar-animation.js<br/>initPollAnimation()"]
Entry --> ThemeToggleIAA["iaa-alliance-theme-toggle.js<br/>initIAAThemeToggle()"]
Entry --> Search["search-functionality.js<br/>initSearch()"]
Entry --> Newsletter["newsletter-spam-protection.js<br/>initNewsletterSpamProtection()"]
Entry --> ThemeObs["theme-toggling.js<br/>initThemeToggling()"]

Diagram sources

  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)
  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [custom-cursor.js:1-28](file://src/assets/js/modules/custom-cursor.js#L1-L28)
  • [hero-animations.js:1-307](file://src/assets/js/modules/hero-animations.js#L1-L307)
  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)
  • [carousel-system.js:1-169](file://src/assets/js/modules/carousel-system.js#L1-L169)
  • [team-card-flip.js:1-14](file://src/assets/js/modules/team-card-flip.js#L1-L14)
  • [accordion.js:1-35](file://src/assets/js/modules/accordion.js#L1-L35)
  • [poll-bar-animation.js:1-20](file://src/assets/js/modules/poll-bar-animation.js#L1-L20)
  • [material-design-3-main-theme-toggle.js:1-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L1-L38)
  • [iaa-alliance-theme-toggle.js:1-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L1-L38)
  • [search-functionality.js:1-179](file://src/assets/js/modules/search-functionality.js#L1-L179)
  • [newsletter-spam-protection.js:1-24](file://src/assets/js/modules/newsletter-spam-protection.js#L1-L24)

Section sources

  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)
  • [package.json:1-32](file://package.json#L1-L32)

Core Components

  • main.js orchestrates initialization by importing individual init functions and invoking them in a deliberate order after DOMContentLoaded. It conditionally enables advanced animations and interactions when GSAP and related plugins are available.
  • Each module encapsulates a single responsibility and exports an init function that performs feature-specific setup and teardown hooks where applicable.
  • Progressive enhancement ensures core UX remains intact even if JavaScript fails or is disabled. Advanced features like animations, carousels, and search rely on optional libraries and are guarded by checks.

Key orchestration highlights:

  • Import pattern: Named imports per module init function.
  • Initialization sequence: Navigation and theme toggles first, followed by layout polish, then interactive components, and finally animations gated by library availability.
  • Conditional loading: Advanced features activate only when external libraries are present; otherwise, a warning is logged and core features remain functional.

Section sources

  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)

Architecture Overview

The runtime architecture follows a modular initialization model:

  • Entry point registers a DOMContentLoaded listener.
  • On activation, it invokes a fixed sequence of init functions.
  • Optional features are guarded by runtime checks for global libraries.
  • Cleanup and accessibility attributes are applied where appropriate.
sequenceDiagram
participant Browser as "Browser"
participant Main as "main.js"
participant Nav as "navigation.js"
participant Theme as "theme-toggling.js"
participant Cursor as "custom-cursor.js"
participant Hero as "hero-animations.js"
participant Polish as "scroll-nav-polish.js"
participant Carousels as "carousel-system.js"
participant Team as "team-card-flip.js"
participant Acc as "accordion.js"
participant Poll as "poll-bar-animation.js"
participant MT as "material-design-3-main-theme-toggle.js"
participant IAA as "iaa-alliance-theme-toggle.js"
participant Search as "search-functionality.js"
participant NL as "newsletter-spam-protection.js"
Browser->>Main : DOMContentLoaded
Main->>Nav : initNavigation()
Main->>Theme : initThemeToggling()
Main->>Team : initTeamCardFlip()
Main->>Carousels : initCarousels()
Main->>Acc : initAccordion()
Main->>Polish : initScrollPolish()
Main->>Poll : initPollAnimation()
Main->>MT : initThemeToggle()
Main->>Search : initSearch()
Main->>IAA : initIAAThemeToggle()
Main->>NL : initNewsletterSpamProtection()
alt GSAP available
Main->>Cursor : initCustomCursor()
Main->>Hero : initHeroAnimations()
Main->>Hero : initScrollReveals()
else GSAP missing
Main-->>Browser : warn and continue core features
end

Diagram sources

  • [main.js:15-36](file://src/assets/js/main.js#L15-L36)
  • [navigation.js:3-78](file://src/assets/js/modules/navigation.js#L3-L78)
  • [theme-toggling.js:3-24](file://src/assets/js/modules/theme-toggling.js#L3-L24)
  • [custom-cursor.js:3-28](file://src/assets/js/modules/custom-cursor.js#L3-L28)
  • [hero-animations.js:3-307](file://src/assets/js/modules/hero-animations.js#L3-L307)
  • [scroll-nav-polish.js:3-19](file://src/assets/js/modules/scroll-nav-polish.js#L3-L19)
  • [carousel-system.js:3-169](file://src/assets/js/modules/carousel-system.js#L3-L169)
  • [team-card-flip.js:3-14](file://src/assets/js/modules/team-card-flip.js#L3-L14)
  • [accordion.js:3-35](file://src/assets/js/modules/accordion.js#L3-L35)
  • [poll-bar-animation.js:3-20](file://src/assets/js/modules/poll-bar-animation.js#L3-L20)
  • [material-design-3-main-theme-toggle.js:3-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L3-L38)
  • [iaa-alliance-theme-toggle.js:3-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L3-L38)
  • [search-functionality.js:3-179](file://src/assets/js/modules/search-functionality.js#L3-L179)
  • [newsletter-spam-protection.js:3-24](file://src/assets/js/modules/newsletter-spam-protection.js#L3-L24)

Detailed Component Analysis

Navigation Module

Responsibilities:

  • Toggles mobile menu state.
  • Manages focus trapping and escape key behavior.
  • Closes menu on outside clicks and link selection.
  • Sets ARIA attributes for accessibility.

Lifecycle:

  • Initializes on DOMContentLoaded.
  • Event listeners attached and removed implicitly by browser GC; no explicit teardown method is exported.

Accessibility:

  • Updates aria-expanded and aria-label on toggle.
  • Focuses first link after opening animation.
  • Traps Tab focus within the menu.

Section sources

  • [navigation.js:3-78](file://src/assets/js/modules/navigation.js#L3-L78)

Theme Toggling (Section Observer)

Responsibilities:

  • Observes sections with data-theme to switch body classes dynamically as the user scrolls through themed regions.

Lifecycle:

  • Creates an IntersectionObserver with rootMargin and threshold configured for smooth transitions.
  • No explicit teardown; observer remains active for the page lifetime.

Section sources

  • [theme-toggling.js:3-24](file://src/assets/js/modules/theme-toggling.js#L3-L24)

Custom Cursor (Desktop Only)

Responsibilities:

  • Provides desktop hover effects with GSAP-managed tweens.
  • Disables itself on coarse-pointer devices or small screens.

Lifecycle:

  • Checks device capability early and returns if conditions are not met.
  • Uses mousemove to track pointer and GSAP to animate followers.

Cleanup:

  • No explicit removal; relies on event listeners being garbage collected when the page unloads.

Section sources

  • [custom-cursor.js:3-28](file://src/assets/js/modules/custom-cursor.js#L3-L28)

Hero Animations (GSAP)

Responsibilities:

  • Conditionally initializes particle backgrounds, SVG line draws, parallax effects, and a split-flap flipboard reveal.
  • Uses ScrollTrigger for scroll-linked animations and IntersectionObserver for offscreen reveals.

Lifecycle:

  • Guarded by presence of GSAP and ScrollTrigger.
  • Uses gsap.ticker and ScrollTrigger.create for animation loops and triggers.
  • Reduces motion support via reduced-motion detection.

Cleanup:

  • No explicit teardown; ticker and observers persist for the page lifetime.

Section sources

  • [hero-animations.js:3-307](file://src/assets/js/modules/hero-animations.js#L3-L307)

Scroll Navigation Polish

Responsibilities:

  • Adjusts navigation padding and shadow based on scroll position.

Lifecycle:

  • Attaches a passive scroll listener.
  • No explicit teardown.

Section sources

  • [scroll-nav-polish.js:3-19](file://src/assets/js/modules/scroll-nav-polish.js#L3-L19)

Carousel System

Responsibilities:

  • Configures multiple carousels with pagination dots, keyboard navigation, drag-to-scroll, and responsive snapping.
  • Computes snap points based on viewport width and item sizing.

Lifecycle:

  • Renders dots and updates state on scroll and resize.
  • Uses passive listeners for performance.

Cleanup:

  • No explicit teardown; relies on GC.

Section sources

  • [carousel-system.js:3-169](file://src/assets/js/modules/carousel-system.js#L3-L169)

Team Card Flip (Touch Devices)

Responsibilities:

  • Enables flipping of team cards on click for touch devices.

Lifecycle:

  • Checks for hover: none media query and returns otherwise.
  • Adds click listeners to cards.

Section sources

  • [team-card-flip.js:3-14](file://src/assets/js/modules/team-card-flip.js#L3-L14)

Accordion

Responsibilities:

  • Manages expand/collapse of accordion items with sibling collapse behavior.
  • Calculates inner content height for smooth transitions.

Lifecycle:

  • Adds click listeners to headers and toggles classes/styles accordingly.

Section sources

  • [accordion.js:3-35](file://src/assets/js/modules/accordion.js#L3-L35)

Poll Bar Animation

Responsibilities:

  • Animates poll segments to their final width when they become visible.

Lifecycle:

  • Uses IntersectionObserver to trigger width changes.

Section sources

  • [poll-bar-animation.js:3-20](file://src/assets/js/modules/poll-bar-animation.js#L3-L20)

Material Design 3 Theme Toggle

Responsibilities:

  • Persists theme preference in localStorage and applies body classes.
  • Supports keyboard activation.

Lifecycle:

  • Reads saved preference on load and sets aria-checked.
  • No explicit teardown.

Section sources

  • [material-design-3-main-theme-toggle.js:3-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L3-L38)

IAA Alliance Theme Toggle

Responsibilities:

  • Independent theme toggle for the alliance interface with its own storage key.

Lifecycle:

  • Same pattern as main theme toggle but scoped to alliance context.

Section sources

  • [iaa-alliance-theme-toggle.js:3-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L3-L38)

Search Functionality (Pagefind)

Responsibilities:

  • Lazy-loads Pagefind on demand, debounces input, renders results, supports keyboard navigation, and opens/closes modal.
  • Integrates with a modal UI and overlay.

Lifecycle:

  • loadPagefind is memoized to avoid repeated imports.
  • Debounces search input and clears selection state on close.
  • Keyboard shortcuts include Escape and Command/Ctrl+K.

Cleanup:

  • No explicit teardown; modal and listeners removed on close.

Section sources

  • [search-functionality.js:3-179](file://src/assets/js/modules/search-functionality.js#L3-L179)

Newsletter Spam Protection

Responsibilities:

  • Adds a honeypot field to ConvertKit forms and prevents submission if bot heuristics are triggered.

Lifecycle:

  • Attaches submit listeners and checks for honeypot value and time since page load.

Section sources

  • [newsletter-spam-protection.js:3-24](file://src/assets/js/modules/newsletter-spam-protection.js#L3-L24)

Dependency Analysis

  • Runtime dependencies:
    • GSAP and ScrollTrigger are optional; animations are gated by presence checks.
    • Pagefind is lazily imported for search functionality.
  • Build-time dependency:
    • Pagefind indexing is integrated via an Eleventy script in package.json.
graph LR
Main["main.js"] --> GSAP["GSAP (optional)"]
Main --> ST["ScrollTrigger (optional)"]
Main --> PF["Pagefind (optional)"]
Build["package.json scripts"] --> PFBuild["pagefind --site _site"]

Diagram sources

  • [main.js:28-35](file://src/assets/js/main.js#L28-L35)
  • [search-functionality.js:18-28](file://src/assets/js/modules/search-functionality.js#L18-L28)
  • [package.json:6](file://package.json#L6)

Section sources

  • [main.js:28-35](file://src/assets/js/main.js#L28-L35)
  • [search-functionality.js:18-28](file://src/assets/js/modules/search-functionality.js#L18-L28)
  • [package.json:6](file://package.json#L6)

Performance Considerations

  • Passive event listeners:
    • Scroll and resize listeners use passive: true to avoid layout thrashing.
    • Example: scroll-nav-polish.js and carousel-system.js apply passive listeners.
  • IntersectionObserver for reveals:
    • hero-animations.js uses IntersectionObserver to avoid continuous ticking.
  • Debounced search:
    • search-functionality.js debounces input to reduce re-renders.
  • Conditional feature activation:
    • main.js guards advanced animations behind GSAP availability to prevent unnecessary work.
  • Memory management:
    • Modules generally do not export teardown functions; reliance on implicit GC is acceptable for page-lifetime features.
  • Lazy loading:
    • Pagefind is dynamically imported only when the search modal opens.
  • Bundling and delivery:
    • Consider bundling shared libraries (e.g., GSAP) and ensuring they are cached effectively.
    • Keep module sizes small and tree-shakeable to minimize payload.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common initialization failures and debugging techniques:

  • GSAP not loaded:
    • Symptom: Console warning about GSAP not loaded; animations skipped.
    • Action: Verify external library inclusion and network availability.
    • Reference: [main.js:28-35](file://src/assets/js/main.js#L28-L35)
  • Pagefind not available:
    • Symptom: Search modal shows “Search unavailable”.
    • Action: Confirm Pagefind is built and served at the expected path; check network tab for errors.
    • Reference: [search-functionality.js:24-27](file://src/assets/js/modules/search-functionality.js#L24-L27)
  • Missing DOM elements:
    • Symptom: Feature does nothing (returns early).
    • Action: Inspect selectors and confirm markup exists.
    • References:
      • [navigation.js:6](file://src/assets/js/modules/navigation.js#L6)
      • [carousel-system.js:18](file://src/assets/js/modules/carousel-system.js#L18)
      • [custom-cursor.js:6](file://src/assets/js/modules/custom-cursor.js#L6)
  • Accessibility regressions:
    • Symptom: Focus trap or ARIA states incorrect.
    • Action: Verify aria-expanded, aria-label, and focus management.
    • References:
      • [navigation.js:12-26](file://src/assets/js/modules/navigation.js#L12-L26)
      • [material-design-3-main-theme-toggle.js:15](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L15)
  • Scroll performance issues:
    • Symptom: Jank during scroll.
    • Action: Ensure passive listeners are used; avoid synchronous layout reads in scroll handlers.
    • Reference: [scroll-nav-polish.js:15](file://src/assets/js/modules/scroll-nav-polish.js#L15)
  • Carousel snapping anomalies:
    • Symptom: Dots out of sync or snap points incorrect.
    • Action: Check item widths, gaps, and resize handling.
    • Reference: [carousel-system.js:34-71](file://src/assets/js/modules/carousel-system.js#L34-L71)

Section sources

  • [main.js:28-35](file://src/assets/js/main.js#L28-L35)
  • [search-functionality.js:24-27](file://src/assets/js/modules/search-functionality.js#L24-L27)
  • [navigation.js:6](file://src/assets/js/modules/navigation.js#L6)
  • [carousel-system.js:18](file://src/assets/js/modules/carousel-system.js#L18)
  • [custom-cursor.js:6](file://src/assets/js/modules/custom-cursor.js#L6)
  • [scroll-nav-polish.js:15](file://src/assets/js/modules/scroll-nav-polish.js#L15)
  • [carousel-system.js:34-71](file://src/assets/js/modules/carousel-system.js#L34-L71)

Conclusion

The main.js orchestrator establishes a clean, predictable initialization sequence for the frontend modules. By structuring each feature as a self-contained init function and guarding advanced features behind runtime checks, the system achieves progressive enhancement. The documented patterns—conditional loading, passive listeners, debouncing, and accessibility—provide a robust foundation for maintainability and performance. Extending the system involves adding a new module with an init function and registering it in main.js following the established order and guard patterns.